package com.wjm.set;

import java.util.HashSet;
import java.util.Objects;

/**
 * Data:2022年07月07日
 * Author:wjm
 * Content: HashSet中如何保证元素不重复
 *
 *
 *  在JDK1.8之后，HashSet中加入了红黑树，优化了其底层存储的性能，如果一个格子中(桶)的元素大于8(阈值)个，
 *  则，存储结构会自动从链表结构转为红黑树，这样做的原因是：因为链表不利于查询，转成红黑树可以增加查询效率。
 *
 *  不重复特性实现的原理：
 *            对于HashSet元素是的唯一性是通过对象的 hashCode()的方法和 equals()方法实现的，首先会判
 *            断，对象的hashcode值是否相等，相同的话就放在一个格子(桶)中，接着通过equals()方法比较内容
 *            是否相同，相同的话就不存储。
 *
 *  注意：如果要将一个类的对象添加到 HashSet集合中一定要重写Object父类的 hashCode()的方法和 equals()
 *
 */
public class HashSetDemo1 {
    public static void main(String[] args) {
        //创建hashset对象
        HashSet<Person> hashSet = new HashSet<>();

        //声明Person对象
        Person p1 = new Person("欧文",30);
        Person p2 = new Person("詹姆斯",37);
        Person p3 = new Person("库里",32);
        Person p4 = new Person("wjm",21);
        Person p5 = new Person("欧文",30);

        //向hashset集合中加元素
        hashSet.add(p1);
        hashSet.add(p2);
        hashSet.add(p3);
        hashSet.add(p4);
        hashSet.add(p5);

        //输出p1~p5的hashcode值
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p3.hashCode());
        System.out.println(p4.hashCode());
        System.out.println(p5.hashCode());

        //输出集合
        System.out.println(hashSet);


    }
}


class Person{
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //重写equals方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                name.equals(person.name);
    }

    //重写hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}